/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ssp.strategy.factory;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import ssp.service.FrontendServer;
import ssp.service.FrontendServerManager;
import ssp.service.ServiceEntry;
import ssp.utility.MersenneTwisterRNG;

/**
 *
 * @author yamazaki
 */
public class CreateServiceEntryStrategy {
    
    /**
     * 各フロントエンドサーバにentryNumずつのServiceEntryを割り当てる
     * @param typeNum
     * @param entryNum
     * @param QoSnum
     * @param QoSrange 
     */
    public static void allocateFlatTypeNum(int typeNum, int entryNum, int QoSnum, int QoSrange) {
        List<Integer> typeIndexList = new ArrayList<Integer>();
        for(int i=0; i< typeNum ; i++) {
            typeIndexList.add(i);
        }
        for(FrontendServer frontendServer : FrontendServerManager.getINSTANCE().getFrontendServerList()) {
            Collections.shuffle(typeIndexList, MersenneTwisterRNG.getINSTANCE());
            for(int i=0 ; i<entryNum ; i++) {
                List<Integer> qos = new ArrayList<Integer>(makeQoS(QoSnum, QoSrange));
                frontendServer.addServiceEntry(new ServiceEntry(typeIndexList.get(i), makeWorkload(qos), qos, makeCharge(qos)));
            }
        }
    }
    
     /**
     * 指定数のQoS指標を生成
     * @param QoSnum QoSの数
     * @param QoSrange QoSの幅
     * @return 
     */
    private static List<Integer> makeQoS(int QoSnum, int QoSrange) {
        List<Integer> QoSindexList = new ArrayList<Integer>();
        for(int i=0 ; i<QoSnum ; i++) {
            QoSindexList.add(MersenneTwisterRNG.getINSTANCE().nextInt(QoSrange));
        }
        return QoSindexList;
    }
    
    /**
     * QoS指標からサービスの処理負荷を生成する
     * @param QoSindexlist QoS指標のリスト
     * @return サービス処理負荷
     */
    private static double makeWorkload(List<Integer> QoSindexlist) {
        double workload = 0.0;
        for(int qos : QoSindexlist) {
            workload += qos * MersenneTwisterRNG.getINSTANCE().nextDouble();
        }
        return workload;
    }
    
    /**
     * QoS指標から利用料金を生成する
     * @param QoSindexlist QoS指標のリスト
     * @return サービス使用料金
     */
    private static double makeCharge(List<Integer> QoSindexlist) {
        double charge = MersenneTwisterRNG.getINSTANCE().nextDouble();
        for(int qos : QoSindexlist) {
            charge += qos * MersenneTwisterRNG.getINSTANCE().nextDouble();
        }
        return charge;
    }
    
}
